package Servidor;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.CallableStatement;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;


import BaseDatos.Coneccion;
import Mensaje.Requerimiento;
import Mensaje.Respuesta;

public class Servidor extends Thread{
	
//poner palabra STATIC
	static VentanaSER v= new VentanaSER();
	
	Socket s;
	Respuesta resp;
	Requerimiento req;
	ObjectInputStream ois;
	ObjectOutputStream oos;
	

	public Servidor(Socket s) {
		this.s=s;
		
	}
	
	public static void main(String[] args)
	{	
		try{	
			Coneccion.odbcDrivers();
			ServerSocket ss=new ServerSocket(10101);
			Socket socket;
			while(true)
			{
				socket=ss.accept();
				new Servidor(socket).start();
				}
		}
		catch(IOException e)
		{
			
		}
	}
	
	public void run(){
		
		try {
			ois=new ObjectInputStream(s.getInputStream());
			oos=new ObjectOutputStream(s.getOutputStream());
			
			req=new Requerimiento(); //recibo un req de conexion por parte del cliente.
			req=(Requerimiento)ois.readObject();
			System.out.println("LEE MENSAJE "+req.getTipo());
			
			if(req.getTipo()==Requerimiento.CONECTAR){
				v.mostrar("Recibi un mensaje del cliente del tipo: "+req.getTipo());
				System.out.println("CONECTAR-SER");
				
				//estos 4 renglones en el caso de que me pida iniciar todo con us y pass del cliente.(archivo.dat)
				String us=req.getUsuario();
				String pass=req.getPassword();
				v.mostrar("USUARIO: "+req.getUsuario());
				v.mostrar("PASWORD: "+req.getPassword());
				
				resp=new Respuesta();
				resp.setTipo(Respuesta.PROCEDIMIENTOS);
				resp.setTitulos(obtenerTitulos(us,pass));
				oos.writeObject(resp);
			}
			else{
				if(req.getTipo()==Requerimiento.REQUERIR){
				v.mostrar("Recibi un mensaje del cliente del tipo: "+req.getTipo());
				System.out.println("REQUERIR-SER");
				String procedure=req.getDato();
				int zona=req.getArgumentos()[0];
				int categoria=req.getArgumentos()[1];
				
				String us=req.getUsuario();
				String pass=req.getPassword();
				
				resp=new Respuesta();
				resp.setTipo(Respuesta.CONSULTA);
				resp.setTitulos(obtenerEncabezado(us,pass,procedure,zona,categoria));
				//resp.setDatos(ejecutarProcedure(us,pass,procedure,zona,categoria));
				//resp.setDatos(null);
				oos.writeObject(resp);
				}
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private Object[][] ejecutarProcedure(String us, String pass, String procedure, int zona, int categoria) {
		
		Object [][] resultado = new Object[300][300];
		Coneccion c = new Coneccion();
		c.conectar(us, pass);
		System.out.println("obtener datos");
		try {
			CallableStatement cst = c.getCon().prepareCall(" {call "+procedure+"(?,?)}");
			cst.setInt(1, zona);
			cst.setInt(2, categoria);
			ResultSet rst= cst.executeQuery();
			ResultSetMetaData rsm = rst.getMetaData();//recupero los datos para cargarlos en una tabla.
			int i=1;
			int j=1;
			while(rst.next()){
			resultado[i][j] = new Object();
				for( j=1; j<= rsm.getColumnCount();j++){
				resultado[i][j]=rst.getObject(j);
				System.out.println(resultado[1][1]);
				}
				i++;
			}
		}catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		return resultado;
	}

	private Object[] obtenerEncabezado(String us, String pass, String procedure, int zona, int categoria) {
		
		Object [] resultado = new Object[10];
		Coneccion c = new Coneccion();
		c.conectar(us, pass);
		
		try {
			System.out.println("obtener encabezados");
			CallableStatement cst = c.getCon().prepareCall(" {call "+procedure+"(?,?)}");
			cst.setInt(1, zona);
			cst.setInt(2, categoria);
			ResultSet rst= cst.executeQuery();
			ResultSetMetaData rsm = rst.getMetaData();//recupero los datos para cargarlos en una tabla.
			
			for(int i=1; i<= rsm.getColumnCount();i++){//siempre arranca de 1, nunca de 0.
				resultado[i]=rsm.getColumnName(i);
				System.out.println(resultado[i]);
			}
		
		} catch (SQLException e1) {
			
			e1.printStackTrace();
		}
	return resultado;
	}

	//funcionaaa
	private static Object[] obtenerTitulos(String us, String pass) {
		
		Object[] ob= new Object[10];
		Coneccion c = new Coneccion();
		c.conectar(us, pass);
		System.out.println("obtener titulos");
		v.mostrar("Obteniendo los procedures");
		try {
			PreparedStatement spm=c.getCon().prepareStatement(c.getSPS());
			ResultSet rs=spm.executeQuery();
			
			int i=0;
			while(rs.next()){
				ob[i++]=rs.getString(1);
			}
			
		} catch (SQLException e) {
			
			e.printStackTrace();
		}
		
		return ob;
	}
	
	
	
}
